#include "V4L2CaptureThread.h"
#include "jpegcompress.h"
#include "log_api.h"

#include "Utils.h"

V4L2CaptureThread::V4L2CaptureThread():OSThread(),
m_frameBuffer(NULL),m_frameSize(0),m_mutex(),m_cond()
{
	memset(&m_frametimestamp,0,sizeof(m_frametimestamp));
}

V4L2CaptureThread::~V4L2CaptureThread()
{

}
int V4L2CaptureThread::Initialize(/*StreamServer* pServer*/)
{
	m_Controller.Initialize("/dev/video0",1280,720,30,V4L2_PIX_FMT_YUYV);
	m_frameBuffer = (unsigned char*)malloc(m_Controller.GetFrameSize());
	if(m_frameBuffer == NULL) {
        fprintf(stderr, "could not allocate memory\n");
        exit(EXIT_FAILURE);
    }
   // m_pServer = pServer;
    Start();
}
void V4L2CaptureThread::Entry()
{
    fprintf(stderr,"V4L2CaptureThread:mutex=%p\n",&m_mutex);
    fprintf(stderr,"V4L2CaptureThread:cond=%p\n",&m_cond);
    SInt64 mill = 0;
	while(1)
	{
		if(m_Controller.GrabUVC() < 0)
		{
			fprintf(stderr,"Error grabbing frames\n");
			exit(EXIT_FAILURE);
		}
        {
        OSMutexLocker locker(&m_mutex);
        //m_mutex.Lock();
		if((m_Controller.GetFormat() == V4L2_PIX_FMT_YUYV) ||
			(m_Controller.GetFormat() == V4L2_PIX_FMT_UYVY) ||
			(m_Controller.GetFormat() == V4L2_PIX_FMT_RGB565) )
		{
			m_frameSize = CompressImageToJpeg(m_Controller.GetFrameBuffer(),
                                              m_Controller.GetWidth(),
                                              m_Controller.GetHeight(),
                                              m_Controller.GetFormat(),
                                              m_frameBuffer,
                                              m_Controller.GetFrameSize(),
                                              80);
			m_frametimestamp = m_Controller.GetFrametimestamp();

            printf("GetOneFrame : JPEG:%ld,YUV=%ld\n",m_frameSize,m_Controller.GetFrameSize());
		}
		else
		{
			m_frameSize = CopyPicture();
            //printf("framesize=%d\n",m_frameSize);
            mill = Utils::Milliseconds();
            //printf("GetOneFrame : %ld\n",mill);
			m_frametimestamp = m_Controller.GetTmptimestamp();
		}
		//if(m_frameBuffer != NULL && m_frameSize > 0)
        //    m_pServer->SendStreamToClient((char*)m_frameBuffer,m_frameSize);
		/* signal fresh_frame */
       	m_cond.Broadcast();
        //m_mutex.Unlock();
        }
	}
}

int V4L2CaptureThread::CopyPicture()
{
	unsigned char *ptcur = m_Controller.GetTmpBuffer();
    int pos = 0,size = m_Controller.GetTmpBufferUsed();

	memcpy(m_frameBuffer + pos, ptcur, size); 
	pos += size;
	return pos;
}
